package com.xiaoyu.web.handler;

import com.xiaoyu.core.domain.Result;
import com.xiaoyu.core.enums.StatusCode;
import com.xiaoyu.core.exception.AuthorizationException;
import com.xiaoyu.core.exception.BuzzException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Optional;

/**
 * 全局异常兜底增强处理
 * @Author：xiaoyu
 * @data: 2023/6/30 14:41
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 未登录类异常
     */
    @ExceptionHandler({AuthorizationException.class})
    public Result handleNoAuthorization(AuthorizationException ex, HttpServletRequest request) {
        log.error("请求地址url:{},异常信息:{}", request.getRequestURI(), ex.getMessage());
        String redirect = "/views/login.html";
        return Result.failure(ex.getMessage(), redirect);
    }

    /**
     *  处理业务异常，断言成功返回，并非系统错误
     * @param ex
     * @param request
     * @return
     */
    @ExceptionHandler({BuzzException.class})
    public Result handleBuzzException(BuzzException ex, HttpServletRequest request) {
        log.error("请求地址uri:{},服务异常:{}", request.getRequestURI(),ex.getMessage());
        ex.printStackTrace();
        return Result.failure(ex.getMessage(), null);
    }

    /**
     * 参数校验异常-单个对象
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleValidation(MethodArgumentNotValidException ex, HttpServletRequest request) {
        log.error("请求地址url:{},参数校验异常信息:{}", request.getRequestURI(), ex.getMessage());
        String defaultMessage = ex.getBindingResult()
                                .getAllErrors()
                                .get(0)
                                .getDefaultMessage();
        return Result.ok(defaultMessage, null);
    }

    /**
     * 参数校验异常-list
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result handleValidation(ConstraintViolationException ex, HttpServletRequest request) {
        log.error("请求地址url:{},参数校验异常信息:{}", request.getRequestURI(), ex.getMessage());
        Optional<ConstraintViolation<?>> first = ex.getConstraintViolations().stream().findFirst();
        ConstraintViolation<?> constraintViolation = first.get();
        String message = constraintViolation.getMessage();
        return Result.ok(message, null);
    }

    /**
     * 全局兜底异常处理
     */
    //@ExceptionHandler(Exception.class)
    public Result handleException(Exception ex, HttpServletRequest request) {
        log.error("请求地址url:{},服务异常:->{}", request.getRequestURI(), ex.getMessage());
        return Result.error(StatusCode.SERVER_ERROR, null);
    }


}
